home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
bavarian
/
121-130
/
125_anwendungen
/
corral
/
corral.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-04
|
12KB
|
481 lines
/*********************************************************
* *
* program: corral *
* ================================== *
* *
* date: 19-JUN-1989 by: ANDREAS NEUPER *
* *
* compile: AZTEC_C3.4 +ff link: -ls -lm -lc +Cb *
* *
* release V1.205 *
* *
* suffix-files, headlines, arg-handling, auto-sizing *
* *
* file-request, centering, turning, 4gadget-handling *
* *
**********************************************************
* *
* BUGS: *
* *
* LACK: *
* *
*********************************************************/
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/display.h>
#include <intuition/intuition.h>
#define dPI 6.2831853072
#define MAX 2000
#define sqr(x) ((x)*(x))
#define wp(x,y) WritePixel(rp,(long)((x)<<1),(long)(y));WritePixel(rp,(long)(((x)<<1)+1),(long)(y))
int Nummer,radius=30,offset=110;
int Menge_x[MAX],Menge_y[MAX];
char titles[90],buf[18];
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct RastPort *rp;
struct Window *window,*strwindow;
struct IntuiMessage *message;
struct Message *GetMsg();
struct Gadget *GadgetPtr;
ULONG MessageClass;
USHORT code;
extern double ran();
extern double sqrt();
unsigned char undostr[100],outstr[100];
struct StringInfo string =
{ outstr,undostr,
0,100,0,0,
0,0,0,0,
NULL,0,NULL
};
short sgp[] =
{
0,0, 322,0, 322,12, 0,12, 0,0
};
struct Border sgb =
{
-2,-2,1,0,JAM1,5,sgp,NULL
};
struct IntuiText sgt =
{
3,0,JAM2,-42,1,NULL,(UBYTE *)"FILE",NULL
};
struct Gadget StrGadg =
{
NULL,
50,5,320,10,
GADGHCOMP,
RELVERIFY|STRINGCENTER,
STRGADGET,
(APTR)&sgb,
NULL,
&sgt,
NULL,
(APTR)&string,
5,NULL
};
short gp[] =
{
0,0, 11,0, 11,11, 0,11, 0,0
};
struct Border gb =
{
-1,-1,1,0,JAM1,5,gp,NULL
};
struct IntuiText gtr =
{
2,0,JAM2,1,1,NULL,(UBYTE *)"R",NULL
};
struct Gadget RotGadg =
{
NULL,
-10,-10,
10, 10,
GADGHCOMP|GRELRIGHT|GRELBOTTOM,
RELVERIFY,
BOOLGADGET,
(APTR)&gb,
NULL,
>r,
NULL,NULL,
4, NULL
};
struct IntuiText gtv =
{
2,0,JAM2,1,1,NULL,(UBYTE *)"V",NULL
};
struct Gadget VerGadg =
{
&RotGadg,
-10, 1,
10, 10,
GADGHCOMP|GRELRIGHT,
RELVERIFY,
BOOLGADGET,
(APTR)&gb,
NULL,
>v,
NULL,NULL,
3, NULL
};
struct IntuiText gth =
{
2,0,JAM2,1,1,NULL,(UBYTE *)"H",NULL
};
struct Gadget HorGadg =
{
&VerGadg,
1,-10,
10,10,
GADGHCOMP|GRELBOTTOM,
RELVERIFY,
BOOLGADGET,
(APTR)&gb,
NULL,
>h,
NULL,NULL,
2, NULL
};
struct IntuiText gtc =
{
2,0,JAM2,1,1,NULL,(UBYTE *)"C",NULL
};
struct Gadget CenterGadg =
{
&HorGadg,
1, 1,
10,10,
GADGHCOMP,
RELVERIFY,
BOOLGADGET,
(APTR)&gb,
NULL,
>c,
NULL,NULL,
1, NULL
};
struct NewWindow nw =
{
18, 8, /* Ecken */
100,60,/*Breit,Hoch*/
3, 1, /* Pens */
CLOSEWINDOW|REFRESHWINDOW|GADGETUP,
WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SUPER_BITMAP|GIMMEZEROZERO,
&CenterGadg,
NULL, /* Gadget Checkmark */
(UBYTE *)"Spektrum Februar 1989",
NULL, /* Zeiger auf Screen */
NULL,/* Zeiger auf SuperBitMap */
40, 20, /* Min. Breit,Hoch */
480,240, /* Max. Breit,Hoch */
WBENCHSCREEN
};
struct NewWindow nw2 =
{
20, 100,
375,30,
2, 1,
CLOSEWINDOW|GADGETUP,
WINDOWCLOSE|BORDERLESS|GIMMEZEROZERO|ACTIVATE,
&StrGadg,
NULL,
(UBYTE *)"OUTPUT_filename: (Spektrum Feb.1989)",
NULL,
NULL,
20, 10,
480,50,
WBENCHSCREEN
};
close_all()
{ extern void CloseLibrary();
extern void CloseWindow();
if (window) CloseWindow(window);
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
exit(FALSE);
}
open_all()
{ void *OpenLibrary();
extern struct Window *OpenWindow();
if (!(GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", (long)0)))
close_all();
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", (long)0)))
close_all();
if (!(window = (struct Window *)
OpenWindow(&nw)))
close_all();
rp = window->RPort;
SetDrMd(rp,JAM1); /* Drawmode setzen */
SetAPen(rp,(long)3); /* Farbregister zum Zeichnen setzen */
}
center()
{ register int i,sumx=0,sumy=0;
int maxrad=0,rad,hoch1=0,hoch2=0,breit1=0,breit2=0;
for(i=0;i<Nummer;i++)
{
sumx += Menge_x[i];
sumy += Menge_y[i];
}
sumx = -sumx/Nummer;
sumy = -sumy/Nummer;
for(i=0;i<Nummer;i++)
{
Menge_x[i] += sumx;
Menge_y[i] += sumy;
rad = sqr(Menge_x[i])+sqr(Menge_y[i]);
if ( rad > maxrad ) maxrad = rad;
if ( Menge_x[i] > breit2 ) breit2 = Menge_x[i];
if ( Menge_y[i] > hoch2 ) hoch2 = Menge_y[i];
if ( Menge_x[i] < breit1 ) breit1 = Menge_x[i];
if ( Menge_y[i] < hoch1 ) hoch1 = Menge_y[i];
}
sprintf(titles,"max. Radius: %.2f Width: %3d Height: %3d Shift(x|y): (%2d |%2d )",
sqrt((double)maxrad),(breit2-breit1),(hoch2-hoch1),sumx,sumy);
SetWindowTitles(window,buf,titles);
}
rotate()
{ register int i,help;
for(i=0;i<Nummer;i++)
{ help = Menge_x[i];
Menge_x[i] = Menge_y[i];
Menge_y[i] = -help;
} }
void shift(shiftn)
int shiftn;
{ register int i;
SetAPen(rp,(long)0);
for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
SetAPen(rp,(long)3);
if (shiftn>0)
{ offset += shiftn;
radius += shiftn;
} else switch(shiftn)
{
case -1 : center();break;
case -2 : for(i=0;i<Nummer;i++) Menge_x[i]=-Menge_x[i];break;
case -3 : for(i=0;i<Nummer;i++) Menge_y[i]=-Menge_y[i];break;
case -4 : rotate();break;
}
if(((offset<<1)+window->TopEdge<240)&&((offset<<2)+window->LeftEdge<475))
SizeWindow(window,(long)((offset<<2)-window->Width),(long)((offset<<1)-window->Height+10));
else {
MoveWindow(window,-1*(long)(window->LeftEdge),-1*(long)(window->TopEdge));
Delay(2L);
if(((offset<<1)+window->TopEdge<240)&&((offset<<2)+window->LeftEdge<475))
SizeWindow(window,(long)((offset<<2)-window->Width),(long)((offset<<1)-window->Height+10));
}
Delay(12L);
for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
RefreshGadgets(&CenterGadg,window,NULL);
}
void eingabe(argc,arg)
int argc;
char **arg;
{ FILE *infile;
char fn[40];
int k,position;
short x,y;
x = window->Width+window->LeftEdge;
y = window->Height+window->TopEdge;
if ( ( argc > 2 ) || ( ( argc == 2 ) && ( arg[1][0] == '?' ) ) )
{ fprintf(stderr,"\n \033[7;30;43m\033[0;33;42m USAGE : \033[0;33m corral [ workFILE ]\033[0;31m\n\n"); close_all(); exit(10); }
if ( argc == 1 )
{ Menge_x[0]=0; Menge_y[0]=0;
Nummer = 1;
radius = 10;
offset = 25;
if (!(strwindow = (struct Window *) OpenWindow(&nw2)))
{
if (strwindow) CloseWindow(strwindow);
close_all();
}
ActivateGadget(&StrGadg,window,NULL);
for(;;)
if (message = (struct IntuiMessage *) GetMsg(strwindow->UserPort))
{
code = message->Code;
MessageClass = message->Class;
GadgetPtr = (struct Gadget *) message->IAddress;
ReplyMsg(message);
if ((MessageClass == GADGETUP)||(MessageClass == CLOSEWINDOW))
{ if (strwindow) CloseWindow(strwindow);
break;
} }
infile = fopen(outstr,"r");
} else infile = fopen(arg[1],"r");
if ( infile == (long)0 )
{
Menge_x[0]=0; Menge_y[0]=0;
Nummer = 1;
radius = 10;
offset = 25;
} else {
fscanf(infile,"%d",&Nummer);
for(k=0;k<Nummer;k++) fscanf(infile,"%d%d",&Menge_x[k],&Menge_y[k]);
fclose(infile);
radius = (int)(sqrt((double)Nummer)*2)+2;
offset = radius+5;
if (Nummer<75) offset=25;
if (offset < 120) shift(0);
else {fprintf(stderr,"Too many particles!\n");close_all();}
}
RefreshGadgets(&CenterGadg,window,NULL);
}
void ausgabe(argc,argv)
int argc;
char **argv;
{ FILE *outfile;
char fn[100],*help1;
unsigned char *help2;
register int j,k;
if ( argc < 2 )
{
help1=fn;help2=outstr; /*warning ok!*/
while((*help1 = *help2++)&&(*help2 != '.'))help1++;
*(help1+1) = '\0';
} else {
k=strlen(argv[1]);
for(j=0;(j<k)&&(argv[1][j]!='.');j++) fn[j] = argv[1][j];
fn[j] = (char)0;
}
fn[(k=strlen(fn))]='.';
ftoa((double)Nummer,buf,0,1);
for(j=0;j<6;j++) fn[j+k+1] = buf[j];
outfile = fopen(fn,"w");
if ( outfile == (long)0 ) { fprintf(stderr," \033[0;33mOutput-File cannot be opened by CORRAL !\033[0;31m\n\n"); close_all(); exit(5); }
fprintf(outfile,"%d\n",Nummer);
for(k=0;k<Nummer;k++) fprintf(outfile,"%d %d\n",Menge_x[k],Menge_y[k]);
fclose(outfile);
}
double random() /* nur etwas langsamer, dafür zufälliger */
{ long timer, *zeroo = 0;
timer = time(zeroo);
return((ran()*.9+(double)(timer%10)/(double)100));
}
void corral(argc,argv)
int argc;
char **argv;
{ register int i,x,y;
register short Kontakt;
int x2,y2,Anzahl,Abstand;
double Wahl,Winkel;
for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
Kontakt = 0;
sprintf(titles,"CORRAL - a Fractal Tree ©JAN");
while(radius<180)
{
Winkel = dPI*Wahl;
x = radius*cos(Winkel);
y = radius*sin(Winkel);
x2 = y2 = Abstand = 0;/* für neues Teilchen NULL setzen */
do {
x2 = x;
y2 = y; /* x3 and y3 o n l y necessary for s.a.w. */
SetAPen(rp,(long)0);
wp(x+offset,y+offset);
do {
Wahl = random(); /* random walk */
if ( Wahl < 0.25 ) --x;
else {
if ( Wahl < 0.5 ) x++;
else {
if ( Wahl < 0.75 ) --y;
else y++;
} }
}while((x == x2) && (y == y2));/* self avoiding walk */
SetAPen(rp,(long)1);
wp(x+offset,y+offset);
Abstand = sqr(x)+sqr(y);
for(i=0;i<Nummer;i++)
{
if( ( (x-1) == Menge_x[i] ) && ( y == Menge_y[i] ) ) Kontakt = 1;
if( ( (x+1) == Menge_x[i] ) && ( y == Menge_y[i] ) ) Kontakt = 1;
if( ( x == Menge_x[i] ) && ( (y-1) == Menge_y[i] ) ) Kontakt = 1;
if( ( x == Menge_x[i] ) && ( (y+1) == Menge_y[i] ) ) Kontakt = 1;
}
}while((Abstand < sqr(radius)) && (Kontakt == 0));
if ( Kontakt == 0 )
{ SetAPen(rp,(long)0);
wp(x+offset,y+offset);
} else {
Menge_x[Nummer] = x;
Menge_y[Nummer++] = y;
Kontakt = 0;
if (Abstand > (sqr(radius)-3)) shift(5);
sprintf(buf,"%d Particles",Nummer);
SetWindowTitles(window,buf,titles);
if (Nummer == (Nummer/100)*100) ausgabe(argc,argv);
}
if (message = (struct IntuiMessage *) GetMsg(window->UserPort))
{ code = message->Code;
MessageClass = message->Class;
GadgetPtr = (struct Gadget *) message->IAddress;
ReplyMsg(message);
if (MessageClass == GADGETUP) shift(-(GadgetPtr->GadgetID));
if (MessageClass == CLOSEWINDOW) return();
} } }
main(argc,argv)
int argc;
char **argv;
{
open_all();
eingabe(argc,argv);
corral(argc,argv);
ausgabe(argc,argv);
center();Delay(100L);
close_all();
}